package server

import (
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"gitee.com/Gakusyun/gakusyun-ws/config"
	"gitee.com/Gakusyun/gakusyun-ws/templates"
	"gitee.com/Gakusyun/gakusyun-ws/utils"
)

// StaticFileServer 静态文件服务器
type StaticFileServer struct {
	config *config.Config
	stats  *utils.ServerStats
	logger any
}

// NewStaticFileServer 创建新的静态文件服务器
func NewStaticFileServer(cfg *config.Config, stats *utils.ServerStats, logger any) *StaticFileServer {
	return &StaticFileServer{
		config: cfg,
		stats:  stats,
		logger: logger,
	}
}

// ServeFile 处理静态文件请求
func (s *StaticFileServer) ServeFile(w http.ResponseWriter, r *http.Request) {
	s.stats.IncrementTotalRequests()
	start := time.Now()

	// 记录请求日志
	utils.LogWithPrintf(s.logger, "[%s] %s %s", r.Method, r.URL.Path, r.RemoteAddr)

	// 构建文件路径
	p := filepath.Join(s.config.StaticFolder, r.URL.Path)
	p = filepath.Clean(p)

	// 安全路径检查
	if !utils.IsSafePath(p, s.config.StaticFolder) {
		s.stats.IncrementErrorCount()
		utils.ErrorResponse(w, "Invalid path", http.StatusBadRequest)
		utils.LogWithPrintf(s.logger, "Invalid path: %s", p)
		return
	}

	// 处理目录请求，查找 index.html
	if strings.HasSuffix(r.URL.Path, "/") {
		indexPath := filepath.Join(p, "index.html")
		if _, err := os.Stat(indexPath); err == nil {
			s.stats.IncrementSuccessCount()
			http.ServeFile(w, r, indexPath)
			utils.LogWithPrintf(s.logger, "Served index: %s (took %v)", indexPath, time.Since(start))
			return
		}
	}

	// 直接提供文件
	if _, err := os.Stat(p); err == nil {
		s.stats.IncrementSuccessCount()
		http.ServeFile(w, r, p)
		utils.LogWithPrintf(s.logger, "Served file: %s (took %v)", p, time.Since(start))
		return
	}

	// 尝试添加 .html 后缀
	if !strings.HasSuffix(p, ".html") {
		p += ".html"
		if _, err := os.Stat(p); err == nil {
			s.stats.IncrementSuccessCount()
			http.ServeFile(w, r, p)
			utils.LogWithPrintf(s.logger, "Served file: %s (took %v)", p, time.Since(start))
			return
		}
	}

	// 如果请求根路径且没有任何文件，显示欢迎页面
	if r.URL.Path == "/" {
		s.serveWelcomePage(w)
		return
	}

	// 404 处理
	s.stats.IncrementNotFoundCount()
	s.serveNotFound(w, r)
}

// serveNotFound 提供 404 页面
func (s *StaticFileServer) serveNotFound(w http.ResponseWriter, r *http.Request) {
	notFoundPath := filepath.Join(s.config.StaticFolder, s.config.NotFoundPage)
	if _, err := os.Stat(notFoundPath); err == nil {
		http.ServeFile(w, r, notFoundPath)
		utils.LogWithPrintf(s.logger, "Served 404: %s", notFoundPath)
	} else {
		utils.ErrorResponse(w, "404 Not Found", http.StatusNotFound)
	}
}

// serveWelcomePage 提供欢迎页面
func (s *StaticFileServer) serveWelcomePage(w http.ResponseWriter) {
	content, err := templates.RenderWelcome(s.stats)
	if err != nil {
		utils.LogWithPrintf(s.logger, "Failed to render welcome template: %v", err)
		utils.ErrorResponse(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "text/html")
	w.Write([]byte(content))

	utils.LogWithPrintf(s.logger, "Served welcome page")
}